﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Threading;
using System.IO;
using System.Net;
using System.Net.Sockets;

namespace ChatServer
{
    /// <summary>
    /// Chat Server
    /// Allow up to 5 clients
    /// When receiving messages : propagate text to others
    /// </summary>
    class Program
    {
        //List<Room> roomList = new List<Room>();

        public static List<Socket> clientList;

        static void Main(string[] args)
        {
            // cfr TcpClient, TcpListener, UdpClient

            Console.WriteLine("Simple Chat Server");

            ThreadStart mainThreadStart = new ThreadStart(AcceptThread);
            Thread mainThread = new Thread(mainThreadStart);
            mainThread.Start();

            Console.ReadLine();

            mainThread.Abort();

            Console.ReadLine();
        }

        public static void AcceptThread()
        {
            try
            {
                Console.WriteLine("Main thread started");

                // create the socket
                Socket listenSocket = new Socket(AddressFamily.InterNetwork,
                                                 SocketType.Stream,
                                                 ProtocolType.Tcp);

                // bind the listening socket to the port
                IPEndPoint ep = new IPEndPoint(IPAddress.Any, 7777);
                listenSocket.Bind(ep);

                ParameterizedThreadStart clientThreadStart;
                Thread clientThread;

                clientList = new List<Socket>();

                // start listening
                while (true)
                {
                    Console.WriteLine("Main thread : listening");
                    listenSocket.Listen(50);
                    Socket newClientSocket = listenSocket.Accept();
                    Console.WriteLine("Main thread : Client Connected");

                    // Create a new thread to communicate with the client
                    clientThreadStart = new ParameterizedThreadStart(ClientThread);
                    clientThread = new Thread(clientThreadStart);
                    clientThread.Start(newClientSocket);
                }
            }
            catch (ThreadAbortException ex)
            {
                Console.WriteLine("Main thread aborted");
            }
            finally
            {

            }
        }
        public static void ClientThread(Object socket)
        {
            Socket clientSocket = null;
            byte[] buffer = null;
            int dataLength =0;
            try
            {
                clientSocket = socket as Socket;
                clientList.Add(clientSocket);     
                Console.WriteLine("Client thread started");

                //clientSocket.Send(Encoding.ASCII.GetBytes("Welcome to Chat Server ! "));
                buffer = new byte[1];
                buffer[0] = 0;

                while (buffer.ToString() != "bye")
                {
                    dataLength = clientSocket.Available;
                    if (dataLength > 0)
                    {
                        buffer = new byte[dataLength];
                        clientSocket.Receive(buffer);
                        Console.WriteLine("[RCV]{0}",Encoding.ASCII.GetString(buffer));
                        foreach (Socket s in clientList)
                        {
                            try
                            {
                                s.Send(buffer);
                            }
                            catch (SocketException sex)
                            {
                                clientList.Remove(clientSocket);    
                            }
                        }
                    }
                }
                clientList.Remove(clientSocket);     

            }
            catch (ThreadAbortException ex)
            {
                Console.WriteLine("Client thread aborted");
            }
            finally
            {

            }

        }
    }
}
